#include "scope.h"
#include "scope_output.h"

scope_adc_data g_scope_dma_points[PINGPONG][SCOPE_ADC_BUFFER_POINTS] __attribute__((aligned(32768)));
static scope_snap_info g_scope_snap_buffer;

static int __no_inline_not_in_flash_func(scope_snap_prepare_data)(void)
{
    if (g_scope_cfg.running) {
        scope_snap_buffer_read(&g_scope_snap_buffer);
    } else {
        scope_snap_psram_read(&g_scope_snap_buffer);
    }
}

static int __no_inline_not_in_flash_func(scope_snap_json_open)(struct fs_file *file, const char *name, void **priv)
{
    static char buffer[HTTP_FS_IV_NUM * SCOPE_BYTES_PER_POINT + 200];
    int len = 0;
    scope_snap_data *data;
    const uint32_t count = sizeof(buffer) - 1;

    // 优化数据准备流程
    scope_snap_prepare_data();    

    // 先写入JSON头部，减少snprintf调用
    const char *status = g_scope_cfg.running ? "Running" : "Stopped";
    len = snprintf(buffer, count,
        "{\n"
        "\"Status\":\"%s\",\n"
        "\"Offset\":%d,\n"
        "\"Points\":[",
        status,
        g_scope_snap_buffer.offset
    );

    data = g_scope_snap_buffer.buffer;
    
    // 优化数据点的处理，减少snprintf调用次数
    char *buf_ptr = buffer + len;
    uint32_t remaining = count - len;
    int written;
    
    // 处理第一个数据点（如果存在）
    if (g_scope_snap_buffer.length > 0) {
        written = snprintf(buf_ptr, remaining, "%d,%d,%d,%d", 
                          data[0].ch0_min, data[0].ch0_max, 
                          data[0].ch1_min, data[0].ch1_max);
        if (written < remaining) {
            buf_ptr += written;
            remaining -= written;
            len += written;
        }
    }
    
    // 处理剩余数据点
    for (int i = 1; i < g_scope_snap_buffer.length && remaining > 20; i++) {
        written = snprintf(buf_ptr, remaining, ",%d,%d,%d,%d", 
                          data[i].ch0_min, data[i].ch0_max, 
                          data[i].ch1_min, data[i].ch1_max);
        if (written < remaining) {
            buf_ptr += written;
            remaining -= written;
            len += written;
        } else {
            // 缓冲区不足
            break;
        }
    }
    
    // 添加JSON结尾
    if (remaining > 5) {
        written = snprintf(buf_ptr, remaining, "]\n}");
        len += written;
    }

    *(int32_t *)priv = 0;
    file->len = len;
    file->index = file->len;
    file->data = buffer;
    file->flags = 0;
    return 1;
}

static void scope_snamp_json_close(struct fs_file *file, void **priv)
{
}

HTTPD_FILE_DEFINE("/snap.json", scope_snap_json_open, NULL, NULL, scope_snamp_json_close);

void scope_snap_set_running(bool running)
{
    if (running) {
        scope_helper_correct_time_div();
        scope_hw_set_sample_rate(g_scope_cfg.rate);
        scope_snap_buffer_start();
        scope_snap_psram_start();
        scope_trigger_start();
        scope_hw_run();
        scope_output_start();
    } else {
        scope_hw_stop();
        scope_snap_psram_stop();
    }
}

void scope_snap_proc_set_running(char *value)
{
    g_scope_cfg.running = !strcmp(value, "1");

    scope_snap_set_running(g_scope_cfg.running);
    log_printf("Running: %s\n", value);
}
HTTPD_CGI_PARAM_DEFINE("Running", scope_snap_proc_set_running);

static void scope_snap_set_scale(int offset, int step)
{
    if (g_scope_cfg.running) {
        scope_snap_buffer_scale(offset, step);
    } else {
        scope_snap_psram_scale(offset, step);
    }
}

static void scope_snap_proc_set_scale(char *value)
{
    int code = atoi(value);
    int offset = (code & 0xffff) - HTTP_FS_IV_NUM / 2;
    int16_t step = code >> 16;

    scope_snap_set_scale(offset, step);
    if (g_scope_cfg.running) {
        scope_hw_stop();
        scope_snap_buffer_start();
        scope_snap_psram_start();
        scope_hw_run();
    }
    log_printf("SnapScale\n");
}
HTTPD_CGI_PARAM_DEFINE("SnapScale", scope_snap_proc_set_scale);


static void scope_snap_proc_set_move(char *value)
{
    int code = atoi(value);

    if (!g_scope_cfg.running) {
        scope_snap_psram_move(code);
    }
    log_printf("SnapMove\n");
}
HTTPD_CGI_PARAM_DEFINE("SnapMove", scope_snap_proc_set_move);

void scope_snap_init(void)
{
    scope_snap_set_running(true);
}
